package machine;

import java.io.*;
import java.util.Vector;

/**
 * Implementa a abstração da memória
 */
class MainMemory
{

    private Vector mem;
    private Vector asm; /// array de instruções
    private Vector ml;  /// array de micro instruções
    private boolean error;


    public MainMemory(String s)
    {
        mem = new Vector();
        asm = new Vector();
        ml = new Vector();
        
        error = false;

        try
        {
            BufferedReader bufferedreader = new BufferedReader(((java.io.Reader) (new FileReader(s))));
            int i = 0;
            String s2 = "";
            String s1;
            while((s1 = bufferedreader.readLine()) != null) 
            {
                i++;
                if(s1.startsWith("**"))
                {
                    ml.add(((Object) (s1.substring(3, s1.length()))));
                } else
                if(s1.startsWith("*"))
                {
                    s2 = s1.substring(2, s1.length());
                } else
                {
                    try
                    {
                        Long.parseLong(s1, 2);
                        mem.add(((Object) (s1.substring(24, 32))));
                        mem.add(((Object) (s1.substring(16, 24))));
                        mem.add(((Object) (s1.substring(8, 16))));
                        mem.add(((Object) (s1.substring(0, 8))));
                        asm.add(((Object) (s2)));
                    }
                    catch(NumberFormatException numberformatexception)
                    {
                        System.err.println("Line " + i + ": " + " Non-binary data.");
                        error = true;
                    }
                }
            }
        }
        catch(FileNotFoundException filenotfoundexception)
        {
            System.err.println("Error: Unable to open " + s + ".");
            error = true;
        }
        catch(IOException ioexception)
        {
            System.err.println("Error reading " + s + ".");
            error = true;
        }
        mem.trimToSize();
        asm.trimToSize();
    }

    public boolean getError()
    {
        return error;
    }

    public String read(String s)
    {
        try
        {
            int i = Integer.parseInt(s, 2);
            String s1 = (String)mem.elementAt(i + 3) + (String)mem.elementAt(i + 2) + (String)mem.elementAt(i + 1) + (String)mem.elementAt(i);
            return s1;
        }
        catch(NumberFormatException numberformatexception)
        {
            System.out.println("Error reading memory address: " + s + ".");
        }
        return null;
    }

    public void write(String s, String s1)
    {
        try
        {
            int i = Integer.parseInt(s, 2);
            if(i + 3 >= mem.size())
            {
                System.out.println("Attempt to write beyond memory.");
            } else
            {
                mem.setElementAt(((Object) (s1.substring(24, 32))), i);
                mem.setElementAt(((Object) (s1.substring(16, 24))), i + 1);
                mem.setElementAt(((Object) (s1.substring(8, 16))), i + 2);
                mem.setElementAt(((Object) (s1.substring(0, 8))), i + 3);
            }
        }
        catch(NumberFormatException numberformatexception)
        {
            System.out.println("Error writing memory address: " + s + ".");
        }
    }

    public String getAsmComment(String s)
    {
        try
        {
            int i = Integer.parseInt(s, 2);
            if(i / 4 >= asm.size())
            {
                return null;
            } else
            {
                return (String)asm.elementAt(i / 4);
            }
        }
        catch(NumberFormatException numberformatexception)
        {
            System.out.println("Error getting comment for address: " + s + ".");
        }
        return null;
    }

    public String getMLComment(String s)
    {
        try
        {
            int i = Integer.parseInt(s, 2);
            if(i / 4 >= ml.size())
            {
                return null;
            } else
            {
                return (String)ml.elementAt(i / 4);
            }
        }
        catch(NumberFormatException numberformatexception)
        {
            System.out.println("Error getting comment for address: " + s + ".");
        }
        return null;
    }

    public Vector getMem()
    {
        return mem;
    }

    public static void main(String args[])
    {
        MainMemory mainmemory = new MainMemory("test.exe");
        System.out.println(mainmemory.read("00"));
        System.out.println(mainmemory.read("01"));
        System.out.println(mainmemory.read("100"));
        mainmemory.write("100", "10101010101010101010101010101010");
        System.out.println(mainmemory.read("100"));
    }

}
